using Slaks.Graphs.GraphBuilder;
namespace Slaks.Graphs.Algorithms.ExperimentalDistances
{
	public class MCSLimitedVertexEdgeFrequency : MCSLimitedDistance
	{
        public MCSLimitedVertexEdgeFrequency()
            : base()
        {
			IsVisible = false;
        }

        public MCSLimitedVertexEdgeFrequency(Graph one, Graph two) 
            : base ( one, two )
        {
			IsVisible = false;
        }		
		public override bool CanOperateOnRepresentation (GraphBuilder.BuilderType builderType)
		{
			switch(builderType)
			{
			case 			 BuilderType.RawFrequencyRepresentationSlaks:
			case BuilderType.NormalizedFrequencyRepresentationSlaks:
				return true;
			}
			return false;
		}

		/// <summary>
		/// MCSlimited
		/// </summary>
		/// <param name="one"></param>
		/// <param name="two"></param>
		/// <returns></returns>
		public override double GetDistance()
		{
			double result;

			Graph maxCommonSubgraph = (one.GetMCS(two));
			double mcsEdgeFrequency = maxCommonSubgraph.GetEdgeFrequency();
			double mcsVertexFrequency = maxCommonSubgraph.GetVertexFrequency();
			double mcsCommonGraphSize = mcsEdgeFrequency + mcsVertexFrequency;

			double graphSizeOneVertexFrequency = one.GetVertexFrequency();
			double graphSizeTwoVertexFrequency = two.GetVertexFrequency();

			double graphSizeOneEdgeFrequency = one.GetEdgeFrequency();
			double graphSizeTwoEdgeFrequency = two.GetEdgeFrequency();

			double limitedSizeOne =
				(graphSizeOneEdgeFrequency > graphSizeOneVertexFrequency) ? graphSizeOneVertexFrequency*2 : graphSizeOneVertexFrequency + graphSizeOneEdgeFrequency;
			double limitedSizeTwo =
				(graphSizeTwoEdgeFrequency > graphSizeTwoVertexFrequency) ? graphSizeTwoVertexFrequency*2 : graphSizeTwoVertexFrequency + graphSizeTwoEdgeFrequency;

			if (limitedSizeOne > limitedSizeTwo)
			{
				result = 1 - mcsCommonGraphSize/limitedSizeOne;
			}
			else
			{
				result = 1 - mcsCommonGraphSize/limitedSizeTwo;
			}

			if (result < 0) result = 0;

			return result;
		}


	}
}